package com.sk.weichat.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Animatable;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.common.logging.FLog;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.backends.pipeline.PipelineDraweeController;
import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.controller.ControllerListener;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.decoder.SimpleProgressiveJpegConfig;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.listener.RequestListener;
import com.facebook.imagepipeline.listener.RequestLoggingListener;
import com.facebook.imagepipeline.request.BasePostprocessor;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.umeng.commonsdk.debug.E;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;

/**
 * @author lzs
 * @date 2019/9/26
 * Email:343067508@qq.com
 **/
public class FrescoUtils {


    private static Map<String, WeakReference<ProgressResponseBody.ProgressListener>> responseBodyMap = new HashMap<>();

    public static final void init(Context context) {
        Set<RequestListener> requestListeners = new HashSet<>();
        requestListeners.add(new RequestLoggingListener());

        OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false) //取消自动重连;
                .addNetworkInterceptor(new Interceptor() {
                    //监听网络图片加载进度
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Response response = chain.proceed(chain.request());
                        String url = response.request().url().toString();
                        //Log.e("lzs", "请求url:" + url);
                        ProgressResponseBody responseBody = new ProgressResponseBody(url, response.body());
                        return response.newBuilder().body(responseBody).build();
                    }
                })
                .build();
        ImagePipelineConfig config = OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient)
                .setRequestListeners(requestListeners)
                .setBitmapsConfig(Bitmap.Config.RGB_565)
                .setDownsampleEnabled(true)//Downsampling，它处理图片的速度比常规的裁剪更快，并且同时支持PNG，JPG以及WEP格式的图片，非常强大。其使用方式也很简单，在配置ResizeOptions方法的基础上，再把ImagePipelineConfig中的Downsampling开关打开即可
                .setDiskCacheEnabled(true)
                .setResizeAndRotateEnabledForNetwork(true)
                .setProgressiveJpegConfig(new SimpleProgressiveJpegConfig())//实现jpg渐进加载效果
                .build();
        Fresco.initialize(context, config);
        FLog.setMinimumLoggingLevel(FLog.VERBOSE);
    }


    public static final void setImageRes(SimpleDraweeView draweeView, int img_res) {
        draweeView.setImageResource(img_res);
    }

    private static final void setImageUrl(final SimpleDraweeView draweeView, String img_url) {
        setImageUrl(draweeView, img_url, 0, 0);
    }

    /**
     * 预处理加载完成的bitmap
     * @param uri
     * @param simpleDraweeView
     * @param postprocessor
     */
    public static final void loadImagePostProcess(Uri uri, SimpleDraweeView simpleDraweeView, BasePostprocessor postprocessor) {
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .setProgressiveRenderingEnabled(true)//渐进加载
                .setLocalThumbnailPreviewsEnabled(true)
                .setPostprocessor(postprocessor)//处理bitmap
                .build();
        PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
                .setImageRequest(request)
                .setOldController(simpleDraweeView.getController()).setAutoPlayAnimations(true).build();
        simpleDraweeView.setController(controller);
    }

    public static void loadImageControllerListener(final SimpleDraweeView simpleDraweeView, String imagePath, final ControllerListener listener) {
        DraweeController controller = Fresco.newDraweeControllerBuilder().setControllerListener(listener).setUri(Uri.parse(imagePath)).build();
        simpleDraweeView.setController(controller);
    }


    public static final void setImageUrl(final SimpleDraweeView draweeView, String img_url, int width, int height) {
        if (TextUtils.isEmpty(img_url))
            return;
        Uri uri;
        if (!img_url.startsWith("http")) {
            uri = Uri.fromFile(new File(img_url));
        } else {
            uri = Uri.parse(img_url);
        }
        ImageRequest request;

        if (width != 0 && height != 0) {
            //Log.e("lzs","width:"+width+" height:"+height);
            request = getResizeImageRequest(uri, width, height);
        } else {
            request = getImageRequest(uri);
        }
        //Log.e("lzs", "height:" + draweeView.getMeasuredHeight()+"  width:"+draweeView.getMeasuredWidth());
        setController(draweeView, request, true);
    }

    public static final void loadFile(SimpleDraweeView draweeView, String imagePath) {
        setImageUrl(draweeView, imagePath);
    }

    public static final void loadFile(SimpleDraweeView draweeView, String imagePath, int width, int height) {
        setImageUrl(draweeView, imagePath, width, height);
    }

    public static final void loadImage(SimpleDraweeView draweeView, String img_url, ProgressResponseBody.ProgressListener progressListener) {
        WeakReference<ProgressResponseBody.ProgressListener> progressListenerRef = new WeakReference<>(progressListener);
        responseBodyMap.put(img_url, progressListenerRef);
        setImageUrl(draweeView, img_url);

    }

    public static final void loadImage(SimpleDraweeView draweeView, String img_url, int width, int height, ProgressResponseBody.ProgressListener progressListener) {
        WeakReference<ProgressResponseBody.ProgressListener> progressListenerRef = new WeakReference<>(progressListener);
        responseBodyMap.put(img_url, progressListenerRef);
        setImageUrl(draweeView, img_url, width, height);
    }

    public static final void loadImage(SimpleDraweeView draweeView, String img_url) {
        setImageUrl(draweeView, img_url);
    }

    private static void setController(SimpleDraweeView draweeView, ImageRequest request, boolean autoPlay) {
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setImageRequest(request)
                .setOldController(draweeView.getController())
                .setAutoPlayAnimations(autoPlay)
                .build();
        draweeView.setController(controller);
    }


    private static ImageRequest getImageRequest(Uri uri) {
        return ImageRequestBuilder.newBuilderWithSource(uri)
                .setProgressiveRenderingEnabled(true)//渐进加载
                .setLocalThumbnailPreviewsEnabled(true)
                .build();
    }

    private static ImageRequest getResizeImageRequest(Uri uri, int width, int height) {
        return ImageRequestBuilder.newBuilderWithSource(uri)
                .setProgressiveRenderingEnabled(true)//渐进加载
                .setLocalThumbnailPreviewsEnabled(true)
                .setResizeOptions(new ResizeOptions(width, height))
                .build();
    }

    public static void setImgUrl(SimpleDraweeView draweeView, String img_url) {
        if (TextUtils.isEmpty(img_url))
            return;
        //Log.e("img", "url:" + img_url);
        Uri uri = Uri.parse(img_url);
        draweeView.setImageURI(uri);
    }


    public static final int px2dp(Context context, int px) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (px / scale + 0.5f);
    }

    public final static int dp2px(Context context, float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }


    public final static class ProgressResponseBody extends ResponseBody {

        Handler handler;

        //回调接口
        public interface ProgressListener {
            /**
             * @param bytesRead     已经读取的字节数
             * @param contentLength 响应总长度
             * @param done          是否读取完毕
             */
            void update(long bytesRead, long contentLength, boolean done);
        }

        private final ResponseBody responseBody;

        private ProgressListener proxyProgressListener = new ProgressListener() {

            @Override
            public void update(long bytesRead, long contentLength, boolean done) {
                //Log.e("lzs", "bytesRead:" + bytesRead + "  contentLength:" + contentLength + " done:" + done);
                WeakReference<ProgressListener> listenerRef = responseBodyMap.get(url);
                if (listenerRef != null && listenerRef.get() != null) {
                    //Log.e("lzs", "progressListener update");
                    listenerRef.get().update(bytesRead, contentLength, done);
                    if (done) {
                        responseBodyMap.remove(url);
                    }
                }
            }
        };
        private BufferedSource bufferedSource;
        String url;

        public ProgressResponseBody(String url, ResponseBody responseBody) {
            this.responseBody = responseBody;
            this.url = url;
            handler = new Handler(Looper.getMainLooper());
        }

        @Override
        public MediaType contentType() {
            return responseBody.contentType();
        }

        @Override
        public long contentLength() {
            return responseBody.contentLength();
        }


        @Override
        public BufferedSource source() {
            if (bufferedSource == null) {
                bufferedSource = Okio.buffer(source(responseBody.source()));
            }
            return bufferedSource;
        }

        private Source source(Source source) {
            return new ForwardingSource(source) {
                long totalBytesRead = 0L;

                @Override
                public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead = super.read(sink, byteCount);
                    totalBytesRead += bytesRead != -1 ? bytesRead : 0;   //不断统计当前下载好的数据
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            //接口回调
                            proxyProgressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
                        }
                    });
                    return bytesRead;
                }
            };
        }
    }
}
